﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using Excel;
using System.Data;
using System;
using System.Text;

public class MyGameTool
{
    private static string EXCEL_PATH = Application.dataPath + "/Editor/ExcelData/";
    
    private static string EXCEL_DATACLASS_PATH = Application.dataPath + "/Scripts/ExcelData/";


    [MenuItem("MyGame/GenerateExcelInfo")]
    public static void GenerateExcelInfo()
    { 
        //拿到目录
        DirectoryInfo excelDirectory = Directory.CreateDirectory(EXCEL_PATH);
        //取得目录下所有文件
        FileInfo[] excelFiles = excelDirectory.GetFiles();

        for (int i = 0; i < excelFiles.Length; i++)
        {
            //如果后缀不是 xls 或者 xlsx 的就跳过
            if (excelFiles[i].Extension != ".xls" && excelFiles[i].Extension != ".xlsx")
            {
                continue;
            }

            DataSet ds;
            using (FileStream fs = excelFiles[i].Open(FileMode.Open, FileAccess.Read))
            {
                IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(fs);

                ds = reader.AsDataSet();

                fs.Close();
            }

            //遍历excel文件中的每个表
            DataTableCollection tableCollection = ds.Tables;

            foreach (DataTable dt in tableCollection)
            {
                //生成对应数据类
                GenerateTableClass(dt);
                //生成 上述数据 的 容器类
                GenerateDataContainer(dt);
                //生成 二进制 文件
                GenerateBinary(dt);
            }

            AssetDatabase.Refresh();
        }
    }

    private static void GenerateBinary(DataTable dt)
    {
        int key = GetKeyColumn(dt);
        if (key == -1)
        {
            return;
        }

        string keyType = dt.Rows[0][key].ToString();

        int cnt = dt.Rows.Count - 4;

        if (!Directory.Exists(BinaryManager.EXCEL_BINARY_PATH))
        {
            Directory.CreateDirectory(BinaryManager.EXCEL_BINARY_PATH);
        }


        using (FileStream fs = File.Open(BinaryManager.EXCEL_BINARY_PATH + dt.TableName + ".sav", FileMode.OpenOrCreate, FileAccess.Write))
        {
            //写入总共要读取数据有多少个
            byte[] bytes = BitConverter.GetBytes(cnt);
            fs.Write(bytes, 0, 4);

            //记录Key的类型
            bytes = Encoding.UTF8.GetBytes(keyType);
            fs.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
            fs.Write(bytes, 0, bytes.Length);

            DataRow typeRow = GetVariableType(dt);
            //存入数据
            for (int i = 4; i < dt.Rows.Count; i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    
                    if (typeRow[j].ToString() == "int")
                    {
                        bytes = BitConverter.GetBytes(int.Parse(dt.Rows[i][j].ToString()));
                        fs.Write(bytes, 0, 4);
                    }
                    else if (typeRow[j].ToString() == "float")
                    {
                        bytes = BitConverter.GetBytes(float.Parse(dt.Rows[i][j].ToString()));
                        fs.Write(bytes, 0, 4);
                    }
                    else if (typeRow[j].ToString() == "bool")
                    {
                        bytes = BitConverter.GetBytes(bool.Parse(dt.Rows[i][j].ToString()));
                        fs.Write(bytes, 0, 1);
                    }
                    else if (typeRow[j].ToString() == "string")
                    {
                        bytes = Encoding.UTF8.GetBytes(dt.Rows[i][j].ToString());
                        fs.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
                        fs.Write(bytes, 0, bytes.Length);
                    }
                }
            }

            fs.Close();
        }

        
    }


    //自动生成数据容器类
    private static void GenerateDataContainer(DataTable dt)
    { 
        int key = GetKeyColumn(dt);
        //证明不需要存储这个数据类的容器
        if (key == -1)
        {
            return;
        }

        DataRow variableType = GetVariableType(dt);

        string str = "using System.Collections.Generic;\n\n";
        str += "public class " + dt.TableName + "Container\n{\n";

        str += "  public Dictionary<" + variableType[key].ToString() + ',' + dt.TableName +
                "> container = new Dictionary<" + variableType[key].ToString() + ',' + dt.TableName + ">();\n}";
        
        File.WriteAllText(EXCEL_DATACLASS_PATH + dt.TableName + "Container.cs", str);
    }

    private static int GetKeyColumn(DataTable dt)
    { 
        DataRow keyRow = dt.Rows[2];
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            if (keyRow[i].ToString() == "key")
            {
                return i;
            }
        }
        return -1;
    }


    //自动生成数据类
    private static void GenerateTableClass(DataTable dt)
    {
        //获取变量名的行
        DataRow variableName = GetVariableName(dt);
        //获取变量的类型
        DataRow variableType = GetVariableType(dt);

        if (!Directory.Exists(EXCEL_DATACLASS_PATH))
        {
            Directory.CreateDirectory(EXCEL_DATACLASS_PATH);
        }

        string str = "public class "+dt.TableName+"\n{";
        for (int i = 0; i < dt.Columns.Count; i++)
        {           
            str += "\n    public " + variableType[i].ToString() + " " + variableName[i].ToString() + ";";
        }
        str += "\n}";
        File.WriteAllText(EXCEL_DATACLASS_PATH + dt.TableName + ".cs", str);
    }

    private static DataRow GetVariableName(DataTable dt)
    { 
        return dt.Rows[0];
    }

    private static DataRow GetVariableType(DataTable dt)
    {
        return dt.Rows[1];
    }


    //想要在菜单栏使用自定义功能，得加特性[MenuItem]
    //至少得有一级目录 如下面中的MyTool
    //[MenuItem("MyTool/Test")]
    public static void ReadExcel()  //必须是静态方法
    {
        //首先将excel文件读进流中
        FileStream fs = File.Open(Application.dataPath + "/Data/PlayerInfo.xlsx", FileMode.Open,FileAccess.Read);

        //引入命名空间 Excel
        //创建 IExcelDataReader  , 将流中数据通过 ExcelReaderFactory 生成 IExcelDataReader对象
        IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(fs);

        //生成 Excel数据类
        DataSet ds = reader.AsDataSet();

        //获取表
        DataTable dt = ds.Tables[0];

        //获取每个单元内容
        for (int k = 0; k < ds.Tables.Count; k++)
        {
            //获取每个表的行数据
            DataTable table = ds.Tables[k];
            for (int i = 0; i < table.Rows.Count; i++)
            {
                Debug.Log("-----------");
                DataRow row = table.Rows[i];
                //获取每一行中每一列的数据
                for (int j = 0; j < table.Columns.Count; j++)
                {
                    Debug.Log(row[j].ToString());
                    //Debug.Log(table.Rows[i][j].ToString());
                }
            }
        }

        fs.Close();
    }


}
